home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / admin / xinetd.2 / xinetd / xinetd.2.1.7-linux.4 / libs / src / misc / cvt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-01  |  2.1 KB  |  134 lines

  1. /*
  2.  * $Id: cvt.c,v 1.2 1995/06/01 01:19:05 chuck Exp $
  3.  *
  4.  * cvt.c - IEEE floating point formatting routines for FreeBSD
  5.  * from GNU libc-4.6.27
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <math.h>
  10.  
  11. #undef    IEEE
  12.  
  13. /*
  14.  *    ecvt converts to decimal
  15.  *    the number of digits is specified by ndigit
  16.  *    decpt is set to the position of the decimal point
  17.  *    sign is set to 0 for positive, 1 for negative
  18.  */
  19.  
  20. #ifdef IEEE
  21.  
  22. static inline int
  23. __isspecial(double f, char *bp)
  24. {
  25.     union ieee754_double *ip = (union ieee754_double *) &f;
  26.  
  27.     if ((ip->ieee.exponent & 0x7ff) != 0x7ff)
  28.         return(0);
  29.     if (ip->ieee.mantissa0 || ip->ieee.mantissa1)
  30.         strcpy(bp, "NaN");
  31.     else if (ip->ieee.negative)
  32.         strcpy(bp, "-Infinity");
  33.     else
  34.         strcpy(bp, "Infinity");
  35.     return(1);
  36. }
  37.  
  38. #define    NDIG    512
  39. #else
  40. #define    NDIG    80
  41. #endif
  42.  
  43. static char*
  44. cvt(double arg, size_t ndigits, int *decpt, int *sign, int eflag)
  45. {
  46.     register int r2;
  47.     double fi, fj;
  48.     register char *p, *p1;
  49.     static char buf[NDIG];
  50.  
  51. #ifdef IEEE
  52.     /* XXX */
  53.     if (__isspecial(arg, buf))
  54.         return(buf);
  55. #endif
  56.     if (ndigits>=NDIG-1)
  57.         ndigits = NDIG-2;
  58.     r2 = 0;
  59.     *sign = 0;
  60.     p = &buf[0];
  61.     if (arg<0) {
  62.         *sign = 1;
  63.         arg = -arg;
  64.     }
  65.     arg = modf(arg, &fi);
  66.     p1 = &buf[NDIG];
  67.     /*
  68.      * Do integer part
  69.      */
  70.     if (fi != 0) {
  71.         p1 = &buf[NDIG];
  72.         while (fi != 0) {
  73.             fj = modf(fi/10, &fi);
  74.             *--p1 = (int)((fj+.03)*10) + '0';
  75.             r2++;
  76.         }
  77.         while (p1 < &buf[NDIG])
  78.             *p++ = *p1++;
  79.     } else if (arg > 0) {
  80.         while ((fj = arg*10) < 1) {
  81.             arg = fj;
  82.             r2--;
  83.         }
  84.     }
  85.     p1 = &buf[ndigits];
  86.     if (eflag==0)
  87.         p1 += r2;
  88.     *decpt = r2;
  89.     if (p1 < &buf[0]) {
  90.         buf[0] = '\0';
  91.         return(buf);
  92.     }
  93.     while (p<=p1 && p<&buf[NDIG]) {
  94.         arg *= 10;
  95.         arg = modf(arg, &fj);
  96.         *p++ = (int)fj + '0';
  97.     }
  98.     if (p1 >= &buf[NDIG]) {
  99.         buf[NDIG-1] = '\0';
  100.         return(buf);
  101.     }
  102.     p = p1;
  103.     *p1 += 5;
  104.     while (*p1 > '9') {
  105.         *p1 = '0';
  106.         if (p1>buf)
  107.             ++*--p1;
  108.         else {
  109.             *p1 = '1';
  110.             (*decpt)++;
  111.             if (eflag==0) {
  112.                 if (p>buf)
  113.                     *p = '0';
  114.                 p++;
  115.             }
  116.         }
  117.     }
  118.     *p = '\0';
  119.     return(buf);
  120. }
  121.  
  122. char*
  123. ecvt(double arg, size_t ndigits, int *decpt, int *sign)
  124. {
  125.     return(cvt(arg, ndigits, decpt, sign, 1));
  126. }
  127.  
  128. char*
  129. fcvt(double arg, size_t ndigits, int *decpt, int *sign)
  130. {
  131.     return(cvt(arg, ndigits, decpt, sign, 0));
  132. }
  133.  
  134.